---
title: page
description: 'Complete API reference for the Stagehand Page object'
icon: 'page'
---
import { V3Banner } from '/snippets/v3-banner.mdx';

<V3Banner />

<CardGroup cols={1}>
<Card title="Page" icon="browser" href="/v3/references/page">
  Learn about the Stagehand Page object and browser navigation
</Card>
</CardGroup>

## Overview

The `page` object is the main interface for interacting with browser pages in Stagehand. It provides standard browser automation capabilities for navigation, interaction, and page inspection.

Access the page object through your Stagehand instance:

```typescript
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
const page = stagehand.context.pages()[0];
```

## Navigation Methods

### goto()

Navigate the page to a URL and wait for a lifecycle state.

```typescript
await page.goto(url: string, options?: GotoOptions): Promise<Response | null>
```

Returns a [Response](/v3/references/response) when the navigation produces a network document request, otherwise `null` (e.g. `data:` URLs or same-document navigations).

<ParamField path="url" type="string" required>
  The URL to navigate to. Can be absolute or relative.
</ParamField>

<ParamField path="waitUntil" type="LoadState" optional>
  When to consider navigation succeeded.

  **Options:**
  - `"load"` - Wait for the load event
  - `"domcontentloaded"` - Wait for DOMContentLoaded event (default)
  - `"networkidle"` - Wait for network to be idle

  **Default:** `"domcontentloaded"`
</ParamField>

<ParamField path="timeoutMs" type="number" optional>
  Maximum time to wait for navigation in milliseconds.

  **Default:** `15000`
</ParamField>

### reload()

Reload the current page.

```typescript
await page.reload(options?: ReloadOptions): Promise<Response | null>
```

Resolves with a [Response](/v3/references/response) for the refreshed document when one is reported, otherwise `null`.

<ParamField path="waitUntil" type="LoadState" optional>
  When to consider reload complete. See `goto()` for options.
</ParamField>

<ParamField path="timeoutMs" type="number" optional>
  Maximum time to wait for reload in milliseconds.

  **Default:** `15000`
</ParamField>

<ParamField path="ignoreCache" type="boolean" optional>
  Whether to bypass the browser cache.

  **Default:** `false`
</ParamField>

### goBack()

Navigate back in browser history.

```typescript
await page.goBack(options?: NavigationOptions): Promise<Response | null>
```

Returns a [Response](/v3/references/response) when the history entry triggers a network fetch; otherwise `null`.

<ParamField path="waitUntil" type="LoadState" optional>
  When to consider navigation complete.
</ParamField>

<ParamField path="timeoutMs" type="number" optional>
  Maximum time to wait in milliseconds.

  **Default:** `15000`
</ParamField>

### goForward()

Navigate forward in browser history.

```typescript
await page.goForward(options?: NavigationOptions): Promise<Response | null>
```

Returns a [Response](/v3/references/response) when the navigation loads a new document from the network; otherwise `null`.

<ParamField path="waitUntil" type="LoadState" optional>
  When to consider navigation complete.
</ParamField>

<ParamField path="timeoutMs" type="number" optional>
  Maximum time to wait in milliseconds.

  **Default:** `15000`
</ParamField>

## Page Information

### url()

Get the current page URL (synchronous).

```typescript
page.url(): string
```

**Returns:** The current page URL as a string.

### title()

Get the current page title.

```typescript
await page.title(): Promise<string>
```

**Returns:** The page title as a string.

## Interaction Methods

### click()

Click at absolute page coordinates.

```typescript
await page.click(x: number, y: number, options?: ClickOptions): Promise<void | string>
```

<ParamField path="x" type="number" required>
  X coordinate in CSS pixels.
</ParamField>

<ParamField path="y" type="number" required>
  Y coordinate in CSS pixels.
</ParamField>

<ParamField path="options" type="object" optional>
  Optional click configuration.

  <Expandable title="properties">
    <ParamField path="button" type="string">
      Mouse button to use: `"left"` | `"right"` | `"middle"`

      Default: `"left"`
    </ParamField>

    <ParamField path="clickCount" type="number">
      Number of consecutive clicks.

      Default: `1`
    </ParamField>

    <ParamField path="returnXpath" type="boolean">
      If `true`, returns the XPath of the clicked element instead of void.

      Default: `false`
    </ParamField>
  </Expandable>
</ParamField>

### type()

Type text into the page (dispatches keyboard events).

```typescript
await page.type(text: string, options?: TypeOptions): Promise<void>
```

<ParamField path="text" type="string" required>
  The text to type.
</ParamField>

<ParamField path="options" type="object" optional>
  Optional typing configuration.

  <Expandable title="properties">
    <ParamField path="delay" type="number">
      Delay between key presses in milliseconds.
    </ParamField>

    <ParamField path="withMistakes" type="boolean">
      Simulates typing with occasional mistakes and corrections.

      Default: `false`
    </ParamField>
  </Expandable>
</ParamField>

### locator()

Create a locator for querying elements.

```typescript
page.locator(selector: string): Locator
```

<ParamField path="selector" type="string" required>
  CSS selector or XPath for the element.
</ParamField>

**Returns:** A `Locator` object for interacting with the element.

## Evaluation

### evaluate()

Evaluate JavaScript code in the page context.

```typescript
await page.evaluate<R, Arg>(
  pageFunctionOrExpression: string | ((arg: Arg) => R | Promise<R>),
  arg?: Arg
): Promise<R>
```

<ParamField path="pageFunctionOrExpression" type="string | function" required>
  JavaScript expression as a string or a function to execute in the page context.
</ParamField>

<ParamField path="arg" type="any" optional>
  Optional argument to pass to the function.
</ParamField>

**Returns:** The result of the evaluation (must be JSON-serializable).

## Initialization Scripts

### addInitScript()

Inject JavaScript that runs before any of the page's scripts on every navigation.

```typescript
await page.addInitScript<Arg>(
  script: string | { path?: string; content?: string } | ((arg: Arg) => unknown),
  arg?: Arg,
): Promise<void>
```

<ParamField
  path="script"
  type="string | { path?: string; content?: string } | (arg: Arg) => unknown"
  required
>
  Provide the script to inject. Pass raw source, reference a preload file on disk,
  or supply a function that Stagehand serializes before sending to the browser.
</ParamField>

<ParamField path="arg" type="Arg" optional>
  Extra data that is JSON-serialized and passed to your function. Only supported
  when `script` is a function.
</ParamField>

This method:
- Runs at document start for the current page (including adopted iframe sessions) on every navigation
- Reinstalls the script for all future navigations of this page without affecting other pages
- Mirrors Playwright's `page.addInitScript()` ordering semantics; use  [`context.addInitScript()`](/v3/references/context#addinitscript) to target every page in the context

```typescript
import { Stagehand } from "@browserbasehq/stagehand";

const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
const context = stagehand.context;
const page = await context.awaitActivePage();

await page.addInitScript(() => {
  window.Math.random = () => 42;
});

await page.goto("https://example.com", { waitUntil: "load" });

const result = await page.evaluate(() => Math.random());
console.log("Math.random() returned:", result);

// Math.random() returned: 42
```

## Screenshot

### screenshot()

Capture a screenshot of the page.

```typescript
await page.screenshot(options?: ScreenshotOptions): Promise<Buffer>
```

<ParamField path="fullPage" type="boolean" optional>
  Capture the entire scrollable page instead of just the current viewport.

  **Default:** `false`
</ParamField>

<ParamField path="clip" type="ScreenshotClip" optional>
  Limit the capture to the provided rectangle in CSS pixels (`{ x, y, width, height }`).
  Cannot be combined with `fullPage`.
</ParamField>

<ParamField path="type" type="'png' | 'jpeg'" optional>
  Image format for the screenshot.

  **Default:** `"png"`
</ParamField>

<ParamField path="quality" type="number" optional>
  JPEG quality (0–100). Only used when `type` is `"jpeg"`.
</ParamField>

<ParamField path="scale" type="'css' | 'device'" optional>
  Rendering scale. Use `"css"` for one pixel per CSS pixel, or `"device"` for the
  device pixel ratio.

  **Default:** `"device"`
</ParamField>

<ParamField path="animations" type="'allow' | 'disabled'" optional>
  Control CSS/Web animations and transitions. `"disabled"` fast-forwards finite
  animations and pauses infinite ones before capture.

  **Default:** `"allow"`
</ParamField>

<ParamField path="caret" type="hide | initial" optional>
  Hide the text caret during capture (`"hide"`) or leave it untouched (`"initial"`).

  **Default:** `"hide"`
</ParamField>

<ParamField path="mask" type="Locator[]" optional>
  List of locators to cover with a colored overlay while the screenshot is taken.
</ParamField>

<ParamField path="maskColor" type="string" optional>
  CSS color to use for masked overlays.

  **Default:** `#FF00FF`
</ParamField>

<ParamField path="style" type="string" optional>
  Additional CSS text injected into every frame just before capture. Useful for
  hiding or tweaking dynamic UI.
</ParamField>

<ParamField path="omitBackground" type="boolean" optional>
  Make the default page background transparent (PNG only).

  **Default:** `false`
</ParamField>

<ParamField path="timeout" type="number" optional>
  Maximum time in milliseconds to wait for the capture before throwing.
</ParamField>

<ParamField path="path" type="string" optional>
  Write the screenshot to the provided file path. The image is still returned as
  a buffer.
</ParamField>

**Returns:** A `Promise<Buffer>` containing the screenshot image data.

## Viewport

### setViewportSize()

Set the page viewport size.

```typescript
await page.setViewportSize(
  width: number,
  height: number,
  options?: ViewportOptions
): Promise<void>
```

<ParamField path="width" type="number" required>
  Viewport width in CSS pixels.
</ParamField>

<ParamField path="height" type="number" required>
  Viewport height in CSS pixels.
</ParamField>

<ParamField path="deviceScaleFactor" type="number" optional>
  Device scale factor (pixel ratio).

  **Default:** `1`
</ParamField>

## Wait Methods

### waitForLoadState()

Wait for the page to reach a specific lifecycle state.

```typescript
await page.waitForLoadState(state: LoadState, timeoutMs?: number): Promise<void>
```

<ParamField path="state" type="LoadState" required>
  The lifecycle state to wait for.

  **Options:** `"load"`, `"domcontentloaded"`, `"networkidle"`
</ParamField>

<ParamField path="timeoutMs" type="number" optional>
  Maximum time to wait in milliseconds.

  **Default:** `15000`
</ParamField>


## Events

### on("console")

Listen for console output produced by the page and any adopted iframe sessions. Returns the page instance so calls can be chained.

```typescript
import type { ConsoleMessage } from "@browserbasehq/stagehand";

const handleConsole = (message: ConsoleMessage) => {
  console.log(`[${message.type()}] ${message.text()}`);
  console.log("Arguments:", message.args());
  const location = message.location();
  if (location?.url) {
    console.log(`Emitted from ${location.url}:${location.lineNumber ?? 0}`);
  }
};

page.on("console", handleConsole);
```

`ConsoleMessage` exposes helpers for working with console events:

- `message.type()` – console API category such as `log`, `error`, or `warning`
- `message.text()` – string representation of the console arguments
- `message.args()` – underlying CDP `RemoteObject` arguments array
- `message.location()` – source URL, line, and column when available
- `message.timestamp()` – CDP timestamp for the event
- `message.raw()` – access to the original `Runtime.consoleAPICalledEvent`

### once("console")

Register a listener that removes itself after the first console event.

```typescript
page.once("console", (message) => {
  console.log("First console message:", message.text());
});
```

### off("console")

Remove a previously registered listener. The reference must match the original listener passed to `on()`.

```typescript
page.off("console", handleConsole);
```

## Code Examples

<Tabs>
<Tab title="Basic Navigation">

```typescript
import { Stagehand } from "@browserbasehq/stagehand";

// Initialize with Browserbase (API key and project ID from environment variables)
// Set BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID in your environment
const stagehand = new Stagehand({ env: "BROWSERBASE" });
await stagehand.init();
const page = stagehand.context.pages()[0];

// Navigate to a URL
await page.goto("https://example.com");

// Get current URL and title
console.log("URL:", page.url());
console.log("Title:", await page.title());

// Navigate back and forward
await page.goBack();
await page.goForward();

// Reload the page
await page.reload();
```

</Tab>
<Tab title="Screenshots">

```typescript
// Capture viewport screenshot
const screenshot = await page.screenshot();
await fs.writeFile("screenshot.png", screenshot);

// Capture full page screenshot
const fullPage = await page.screenshot({ fullPage: true });
await fs.writeFile("fullpage.png", fullPage);

// Capture JPEG with styling overrides and a masked element
const styled = await page.screenshot({
  type: "jpeg",
  quality: 80,
  style: "body { filter: grayscale(1); }",
  mask: [page.locator(".ads-banner")],
  maskColor: "rgba(0, 0, 0, 0.3)",
});
await fs.writeFile("styled.jpg", styled);
```

</Tab>
<Tab title="JavaScript Evaluation">

```typescript
// Execute JavaScript expression
const pageHeight = await page.evaluate("document.body.scrollHeight");
console.log("Page height:", pageHeight);

// Execute function with arguments
const result = await page.evaluate((selector) => {
  const element = document.querySelector(selector);
  return element ? element.textContent : null;
}, "h1");
console.log("H1 text:", result);

// Async function evaluation
const data = await page.evaluate(async () => {
  const response = await fetch("/api/data");
  return response.json();
});
```

</Tab>
<Tab title="Interaction">

```typescript
// Click at coordinates
await page.click(100, 200);

// Double click
await page.click(100, 200, { clickCount: 2 });

// Type text
await page.type("Hello, World!");

// Type with delay between keystrokes
await page.type("Slow typing", { delay: 100 });

// Use locator for element interaction
const button = page.locator("button.submit");
await button.click();
```

</Tab>
<Tab title="Wait for Load">

```typescript
// Navigate and wait for full load
await page.goto("https://example.com", {
  waitUntil: "load",
  timeoutMs: 30000
});

// Wait for network idle after navigation
await page.goto("https://spa-app.com", {
  waitUntil: "networkidle"
});

// Wait for specific load state
await page.waitForLoadState("domcontentloaded");
```

</Tab>
<Tab title="Viewport">

```typescript
// Set viewport size
await page.setViewportSize(1920, 1080);

// Set mobile viewport with device scale
await page.setViewportSize(375, 667, {
  deviceScaleFactor: 2
});

// Then take a screenshot at this size
const screenshot = await page.screenshot();
```

</Tab>
</Tabs>

## Types

### LoadState

```typescript
type LoadState = "load" | "domcontentloaded" | "networkidle";
```

- **`"load"`** - Wait for the `load` event (all resources loaded)
- **`"domcontentloaded"`** - Wait for the `DOMContentLoaded` event (DOM is ready)
- **`"networkidle"`** - Wait for network connections to be idle

### AnyPage

```typescript
type AnyPage = PlaywrightPage | PuppeteerPage | PatchrightPage | Page;
```

Stagehand supports multiple browser automation libraries. The `AnyPage` type represents any compatible page object.

### ScreenshotClip

```typescript
interface ScreenshotClip {
  x: number;
  y: number;
  width: number;
  height: number;
}
```

Represents the CSS-pixel rectangle to capture when `clip` is provided.

### ScreenshotOptions

```typescript
interface ScreenshotOptions {
  fullPage?: boolean;
  clip?: ScreenshotClip;
  type?: "png" | "jpeg";
  quality?: number;
  scale?: "css" | "device";
  animations?: "allow" | "disabled";
  caret?: "hide" | "initial";
  mask?: Locator[];
  maskColor?: string;
  style?: string;
  omitBackground?: boolean;
  timeout?: number;
  path?: string;
}
```

Matches Playwright's screenshot signature with sensible defaults to control how a
capture is produced.

## Error Handling

Page methods may throw the following errors:

- **Navigation Errors** - Timeout or network issues during navigation
- **Evaluation Errors** - JavaScript execution errors in `evaluate()`
- **Interaction Errors** - Failed clicks or typing operations
- **Screenshot Errors** - Issues capturing screenshots

All errors should be caught and handled appropriately:

```typescript
try {
  await page.goto("https://example.com");
} catch (error) {
  console.error("Navigation failed:", error.message);
}
```
